package com.kkwrite.regimen.consumer.common;

import com.kkwrite.regimen.consumer.exception.ConsumerException;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang.StringUtils;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.dom.DOMCDATA;
import org.dom4j.io.SAXReader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.io.StringReader;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;

/**
 * Created by lisha on 2018/7/10 20:46.
 *
 * @author lisha
 */
public class WXApi {
    private static final Logger logger = LoggerFactory.getLogger(WXApi.class);

    private WXApi() {
    }

    public static final String RETURN_CODE = "return_code";

    public static final String RETURN_MSG = "return_msg";

    public static final String RESULT_CODE = "result_code";

    public static final String ERR_CODE = "err_code";

    public static final String ERR_CODE_DES = "err_code_des";

    public static final String SUCCESS = "SUCCESS";

    public static final String APP_ID = "wx28c212f657ae0061";

    public static final String APP_SECRET = "06bbecc93220b26a65477d026b2ad350";

    public static final String MCH_ID = "1508479641";

    public static final String WX_PAY_KEY = "hkby1234567890ddddddjkjk6666hkby";

    public static final String TRADE_TYPE = "JSAPI";

    public static final String WX_PAY_NOTIFY_URL = "https://www.diaodiaojiankang.com/order/wxpaynotify";

    public static final String JSCODE_TO_SESSION =
            "https://api.weixin.qq.com/sns/jscode2session?appid=#APPID#&secret=#SECRET#&js_code=#JSCODE#&grant_type=#GRANT_TYPE#";

    public static final String UNIFIED_ORDER = "https://api.mch.weixin.qq.com/pay/unifiedorder";

    public static final String PAY_REFUND = "https://api.mch.weixin.qq.com/secapi/pay/refund";

    public static final String REFUND_NOTIFY_URL = "https://www.diaodiaojiankang.com/order/refund/wxpaynotify";

    public static final String PAY_ORDER_QUERY = "https://api.mch.weixin.qq.com/pay/orderquery";

    public static final String ACCESS_TOKEN = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + APP_ID + "&secret=" + APP_SECRET;

    public static final String WX_CODE_UNLIMIT = "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=#ACCESS_TOKEN#";

    public static String generateNonceStr() {
        return UUID.randomUUID().toString().replaceAll("-", "");
    }

    public static String generateSign(Map<String, String> map) {
        Set<String> keySet = map.keySet();
        String[] keyArray = new String[keySet.size()];
        keyArray = keySet.toArray(keyArray);
        Arrays.sort(keyArray);
        StringBuffer buffer = new StringBuffer();
        Arrays.stream(keyArray).forEach((key) -> {
            String v = map.get(key);
            if (!StringUtils.isBlank(v)) {
                buffer.append("&").append(key).append("=").append(v);
            }
        });
        return DigestUtils.md5Hex(buffer.toString().substring(1) + "&key=" + WX_PAY_KEY).toUpperCase();
    }

    public static Map<String, String> convertString2Map(String xmlString) {
        Map<String, String> map = new HashMap<>(16);
        try (Reader ioReader = new StringReader(xmlString)) {
            @SuppressWarnings("unchecked")
            List<Element> elements = new SAXReader().read(ioReader).getRootElement().elements();
            elements.forEach((e) -> map.put(e.getName(), e.getText()));
        } catch (Exception e) {
            throw new ConsumerException("微信接口调用结果XML转换异常", e);
        }
        return map;
    }

    public static void convertXml2Map(Map<String, String> map, InputStream in) throws DocumentException {
        SAXReader reader = new SAXReader();
        Document document = reader.read(in);
        Element root = document.getRootElement();
        @SuppressWarnings("unchecked")
        List<Element> elementList = root.elements();
        elementList.forEach((e) -> map.put(e.getName(), e.getText()));
        try {
            if (in != null) {
                in.close();
            }
        } catch (IOException e) {
            logger.error(e.getMessage(), e);
        }
    }

    public static String map2XmlString(Map<String, String> map) {
        Document document = DocumentHelper.createDocument();
        Element root = document.addElement("xml");
        document.setRootElement(root);
        map.forEach((k, v) -> {
            if (!StringUtils.isBlank(v)) {
                root.addElement(k).add(new DOMCDATA(v));
            }
        });
        return document.asXML();
    }

}
